/*
作者：flwd
项目名称：ATM系统
实现功能：
1. 注册账户：用户可以输入自己的姓名、密码、取现额度和银行卡号，然后系统会生成一个唯一的银行卡号，并将该用户的账户信息添加到系统中。

2. 登入账户：用户可以输入自己的账户号和密码，然后系统会验证用户的身份，如果验证成功，则允许用户进行其他操作。

3. 查询账户：用户可以查询自己的账户信息，包括账户余额、取现额度和银行卡号。

4. 存款：用户可以输入要存入的金额，然后系统会将该金额添加到用户的账户中。

5. 取款：用户可以输入要取出的金额，然后系统会将该金额从用户的账户中扣除。

6. 转账：用户可以输入要转账的金额和接收账户的账户号，然后系统会将该金额从用户的账户中扣除，并将该金额添加到接收账户的账户中。

7. 修改密码：用户可以输入自己的旧密码和新密码，然后系统会将用户的密码修改为新密码。

8. 注销账户：用户可以选择注销自己的账户，然后系统会删除该用户的账户信息。
 */
package atmSystem;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class ATM {
    public static void main(String[] args) {
        // 创建一个存储账户信息的列表
        ArrayList<Account> accounts = new ArrayList<>();
        System.out.println("欢迎来到深圳职业技术大学银行！");
        // 创建一个 Scanner 对象用于读取用户输入
        Scanner sc = new Scanner(System.in);
        // 进入循环，持续接受用户输入
        while (true) {
            // 打印菜单选项
            System.out.println("请输入指令进行下一步操作");
            System.out.println("1. 登录账户");
            System.out.println("2. 注册账户");

            // 读取用户输入的指令
            int command = sc.nextInt();

            // 根据指令进行相应的操作
            switch (command) {
                case 1:
                    // 调用 login 方法进行账户登录
                    login(accounts,sc);
                    break;
                case 2:
                    // 调用 register 方法进行账户注册
                    register(accounts,sc);
                    break;
                default:
                    // 打印指令输入错误的提示信息
                    System.out.println("您输入的指令有误，请重新输入");
            }
        }
    }

    // 注册账户
    private static void register(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("=========注册账户=========");

        // 创建一个Account对象
        Account account = new Account();

        // 读取并设置用户名
        System.out.println("请输入您的用户名:");
        String n = sc.next();
        account.setName(n);

        // 输入密码，并验证两次输入是否一致
        while (true) {
            System.out.println("请输入您的密码:");
            String Number = sc.next();
            System.out.println("请再次输入您的密码:");
            String okNumber = sc.next();
            if (okNumber.equals(Number)) {
                account.setPassWord(okNumber);
                break;
            } else {
                System.out.println("两次输入密码不一致，请重新输入");
            }
        }

        // 读取并设置单次取现额度
        System.out.println("请输入您单次取现额度:");
        double qm = sc.nextDouble();
        account.setQuoteMoney(qm);

        // 生成并设置卡号
        String Cardid = getRandomCardId(accounts, sc);
        account.setId(Cardid);

        // 将账户添加到账户列表中
        accounts.add(account);

        // 注册成功提示
        System.out.println("注册成功,您的卡号是:" + Cardid + "请您牢记");
    }

    /**
     * 生成一个随机的卡号ID
     * @param accounts 保存卡号的列表
     * @param sc 扫描器对象
     * @return 随机生成的卡号ID
     */
    public static String getRandomCardId(ArrayList<Account> accounts, Scanner sc) {
        Random r = new Random();
        while (true) {
            String id = "";
            for (int i = 0; i < 8; i++) {
                id += r.nextInt(10);//0-9的随机数
            }
            Account acc = getAccountByCardId(accounts, id);
            if (acc == null) {
                return id;
            }
        }
    }


    /**
     * 根据卡号查找对应的账户
     * @param accounts 账户列表
     * @param id 要查找的卡号
     * @return 对应的账户，如果找不到则返回null
     */
    private static Account getAccountByCardId(ArrayList<Account> accounts, String id) {
        for (int i = 0; i < accounts.size(); i++) {
            Account acc = accounts.get(i);
            if(acc.getId().equals(id)) {
                return acc;
            }
        }
        return null;
    }


    private static void login(ArrayList<Account> accounts, Scanner sc) {
        // 如果银行还没有账户，先注册账户
        if (accounts.size() == 0) {
            System.out.println("银行还没有账户，请先注册账户");
            return;
        } else {
            System.out.println("========欢迎光临深圳职业技术大学银行=======");
            System.out.println("===========您已进入登录界面==========");
            // 进入登录循环
            while (true) {
                System.out.println("请输入您的账号:");
                String id = sc.next();
                // 根据账号查找对应的账户
                Account acc = getAccountByCardId(accounts, id);
                // 进入密码输入循环
                while (true) {
                    // 如果账户为空，表示账号有误
                    if (acc == null) {
                        System.out.println("您输入的账号有误，请重新输入");
                        break;
                    } else {
                        System.out.println("请输入您的密码:");
                        String passWord = sc.next();
                        // 比较输入的密码和账户的密码
                        if (passWord.equals(acc.getPassWord())) {
                            System.out.println("登录成功！");
                            // 登录成功后显示用户操作界面
                            showUserCommand(accounts, acc, sc);
                            return;
                        } else {
                            System.out.println("密码有误，请重新输入");
                        }
                    }
                }
            }
        }
    }

    /**
     * 显示用户命令
     * @param accounts 用户账户列表
     * @param acc 当前用户账户
     * @param sc 扫描器对象
     */
    private static void showUserCommand(ArrayList<Account>accounts,Account acc,Scanner sc){
        System.out.println("===========欢迎=========");
        while (true) {
            System.out.println("1.查询");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.转账");
            System.out.println("5.修改密码");
            System.out.println("6.退出");
            System.out.println("7.注销账户");
            System.out.println("8.修改取现额度");
            System.out.println("请选择你要进行的操作:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    search(acc);
                    break;
                case 2:
                    setmoney(acc, sc);
                    break;
                case 3:
                    takeMoney(acc, sc);
                    break;
                case 4:
                    transfer(accounts,acc,sc);
                    break;
                case 5:
                    changePassword(acc,sc);
                    return;				case 6:
                    return;
                case 7:
                    logout(accounts,acc,sc);
                    return;
                case 8:
                    changeQuotemoney(acc,sc);
                    break;
                default:
                    System.out.println("输入有误，请重新输入");
            }
        }
    }


    /**
     * 查询账户信息
     *
     * @param acc 账户对象
     */
    private static void search(Account acc) {
        System.out.println("您好!"+acc.getName()+"先生/女士");
        System.out.println("账号:"+acc.getId());
        System.out.println("当前余额:"+acc.getMoney());
        System.out.println("单次取现额度:"+acc.getQuoteMoney());
    }


    /**
     * 设置账户余额
     *
     * @param acc  账户对象
     * @param sc   扫描器对象，用于接收用户输入
     */
    private static void setmoney(Account acc, Scanner sc) {
        System.out.println("请输入您要存多少钱:");
        double m = sc.nextDouble();
        acc.setMoney(acc.getMoney() + m);
        System.out.println("钱已存入");
    }


    private static void takeMoney(Account acc,Scanner sc) {
        // 循环提示用户输入取现金额
        while (true) {
            System.out.println("请输入您要取多少钱:");
            double m = sc.nextDouble();
            // 循环提示用户重新输入取现金额
            while (true) {
                // 判断取现金额超过账户额度
                if (acc.getQuoteMoney() < m) {
                    System.out.println("超过额度,请重新输入取现金额");
                    break;
                }
                // 判断取现金额超过账户余额
                else if (acc.getMoney() < m) {
                    System.out.println("余额不足,请重新输入取现金额");
                    break;
                }
                // 取现成功，更新账户余额
                else {
                    acc.setMoney(acc.getMoney() - m);
                    System.out.println("钱已取出，请妥善保管");
                    return;
                }
            }
        }
    }


    /**
     * 转账方法
     * @param accounts 账户列表
     * @param acc 转账账户
     * @param sc 扫描器对象
     */
    private static void transfer(ArrayList<Account>accounts,Account acc,Scanner sc) {
        while (true) {
            System.out.println("请输入您要转账对象的账号"); // 提示用户输入转账对象的账号
            String id = sc.next(); // 用户输入的账号
            Account a = getAccountByCardId(accounts, id); // 根据账号获取对应的账户对象
            if (a == null) { // 如果查无此账号
                System.out.println("查无此账号，请重新输入"); // 提示用户重新输入
            } else {
                while (true) {
                    System.out.println("请输入您的转账金额："); // 提示用户输入转账金额
                    double m = sc.nextDouble(); // 用户输入的转账金额
                    if (m > acc.getMoney()) { // 如果转账金额超过账户余额
                        System.out.println("余额不足，请重新输入："); // 提示用户重新输入
                        break; // 退出当前循环，继续下一次循环
                    } else {
                        while (true) {
                            if (m > acc.getQuoteMoney()) { // 如果转账金额超过额度
                                System.out.println("超过额度，请重新输入"); // 提示用户重新输入
                                break; // 退出当前循环，继续下一次循环
                            } else {
                                acc.setMoney(acc.getMoney() - m); // 更新转账账户余额
                                a.setMoney(a.getMoney() + m); // 更新转账对象的余额
                                System.out.println("转账成功！"); // 提示用户转账成功
                                return; // 结束方法
                            }
                        }
                    }
                }
            }
        }
    }


    // 修改密码的方法
    private static void changePassword(Account acc,Scanner sc) {
        while (true) {
            System.out.println("请输入您当前的密码"); // 提示用户输入当前密码
            String p = sc.next(); // 获取用户输入的当前密码

            while (true) {
                if (p.equals(acc.getPassWord())) { // 如果当前密码与账户密码一致
                    System.out.println("请输入您要修改的密码"); // 提示用户输入要修改的密码
                    String password = sc.next(); // 获取用户输入的要修改的密码
                    System.out.println("请再次输入您要修改的密码"); // 提示用户再次输入要修改的密码
                    String OkPassword = sc.next(); // 获取用户输入的确认密码

                    while (true) {
                        if (password.equals(OkPassword)) { // 如果两次输入的密码一致
                            acc.setPassWord(OkPassword); // 修改密码为新密码
                            System.out.println("修改成功！请重新登录");
                            return; // 返回主方法
                        } else {
                            System.out.println("两次输入不一致，请重新输入");
                            break;
                        }
                    }
                } else {
                    System.out.println("密码输入有误，请重新输入");
                    break;
                }
            }
        }
    }


    /**
     * 退出登录函数
     * @param accounts 用户账户列表
     * @param acc 要注销的账户
     * @param sc 扫描器对象
     */
    private static void logout(ArrayList<Account>accounts,Account acc,Scanner sc) {
        System.out.println("您确定要注销账户吗?");
        System.out.println("1.Yes");
        System.out.println("2.No");
        while (true) {
            System.out.println("请输入1或2");
            int judge = sc.nextInt();
            switch (judge) {
                case 1:
                    accounts.remove(acc);
                    System.out.println("注销成功！");
                    return;
                case 2:
                    return;
                default:
                    System.out.println("输入有误");
                    break;
            }
        }
    }


    // 私有方法，用于修改取现额度
    private static void changeQuotemoney(Account acc,Scanner sc) {
        // 显示当前取现额度
        System.out.println("您当前的取现额度是:"+acc.getQuoteMoney());
        while (true) {
            // 提示用户输入密码确保账户的安全
            System.out.println("请输入您的密码确保账户的安全");
            // 获取用户输入的密码
            String p = sc.next();
            // 判断输入的密码是否与账户密码相匹配
            if (p.equals(acc.getPassWord())) {
                // 密码正确
                System.out.println("密码正确。请输入修改后的取现额度：");
                // 获取用户输入的取现额度
                double qm = sc.nextDouble();
                // 设置新的取现额度
                acc.setQuoteMoney(qm);
                // 显示修改成功的提示信息和当前取现额度
                System.out.println("修改成功！当前取现额度是" + acc.getQuoteMoney() + "元");
                return;
            } else {
                // 密码错误，提示用户重新输入
                System.out.println("密码错误，请重新输入");
            }
        }
    }

}
